package com.usian.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.common.wemedia.WemediaConstants;
import com.usian.common.wemedia.WemediaContans;
import com.usian.model.admin.dtos.NewsAuthDto;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.model.media.pojos.WmUser;
import com.usian.model.media.vo.WmNewsVo;
import com.usian.utils.threadlocal.ThreadLocalUtils;
import com.usian.wemedia.mapper.WmMaterialMapper;
import com.usian.wemedia.mapper.WmNewMateriaMapper;
import com.usian.wemedia.mapper.WmNewsMapper;
import com.usian.wemedia.mapper.WmUserMapper;
import com.usian.wemedia.service.WmNewsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends BaseServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Value("${fdfs.url}")
    private String baseUrl;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;
    @Autowired
    private WmNewMateriaMapper wmNewsMaterialMapper;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        if (dto == null) return errorParam;
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        //状态的判断，可以传过去，也可以不传
        wrapper.eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus());
        //频道的判断，可以传过去，也可以不传
        wrapper.eq(dto.getChannelId() != null, WmNews::getChannelId, dto.getChannelId());
        //对标题的模糊查询,可以传过去，也可以不传
        wrapper.like(dto.getKeyword() != null, WmNews::getTitle, dto.getKeyword());
        //如果第一页的展示没有时间
        if (dto.getMaxTime() == null) dto.setMaxTime(new Date());
        wrapper.lt(WmNews::getPublishTime, dto.getMaxTime());
        //排序方式
        wrapper.orderByDesc(WmNews::getPublishTime);
        //只能查询自己的数据通过登录的id
        wrapper.eq(WmNews::getUserId, ThreadLocalUtils.getUserId());
        return getPageData(dto, wrapper);
    }

    @Override
    public ResponseResult saveNews(WmNewsDto wmNews, Short isSubmit) {
        if (wmNews == null) return errorParam;
        WmNews news = new WmNews();
        //把wmNews的值复制到新对象中
        if (wmNews.getType() == -1) wmNews.setType(null);
        BeanUtils.copyProperties(wmNews, news);
        news.setUserId(ThreadLocalUtils.getUserId());
        news.setCreatedTime(new Date());
        news.setSubmitedTime(new Date());
        boolean goAuto = false;
        //判断传过来的id为空则是保存数据，反之修改数据
        if (wmNews.getId() == null) {
            goAuto = save(news);
        } else {
            goAuto = updateById(news);
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));
        }
        saveRelations(wmNews, news);
        if (goAuto) kafkaTemplate.send(WemediaConstants.AUTO_SCAN, news.getId());
        return success;
    }

    @Override
    public ResponseResult findWmNewsById(Integer id) {
        if (id == null) return errorParam;
        WmNews news = getById(id);
        if (news == null) return noData;
        return ResponseResult.okResult(news);
    }

    @Override
    public ResponseResult delNews(Integer id) {
        //1.检查参数
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文章Id不可缺少");
        }
        //2.获取数据
        WmNews wmNews = getById(id);
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
        }

        //3.判断当前文章的状态  status==9  enable == 1
        if (wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode()) && wmNews.getEnable() == 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章已发布，不能删除");
        }

        //4.去除素材与文章的关系
        wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));

        //5.删除文章
        removeById(wmNews.getId());
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        if (dto == null) return errorParam;
        //1.检查参数
        if(dto == null || dto.getId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.查询文章
        WmNews wmNews = getById(dto.getId());
        if(wmNews == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");
        }

        //3.判断文章是否发布
        if(!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"当前文章不是发布状态，不能上下架");
        }

        //4.修改文章状态，同步到app端（后期做）TODO
        if(dto.getEnable() != null && dto.getEnable() > -1 && dto.getEnable() < 2){

            if(wmNews.getArticleId()!=null){
                Map<String,Object> mesMap = new HashMap<>();
                mesMap.put("enable",dto.getEnable());
                mesMap.put("articleId",wmNews.getArticleId());
                kafkaTemplate.send(WemediaContans.WM_NEWS_UP_OR_DOWN_TOPIC,JSON.toJSONString(mesMap));
            }

            update(Wrappers.<WmNews>lambdaUpdate().eq(WmNews::getId,dto.getId()).set(WmNews::getEnable,dto.getEnable()));
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 查询需要发布的文章id列表
     *
     * @return
     */
    @Override
    public List<Integer> findRelease() {
        List<WmNews> list = list(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getStatus, 8).lt(WmNews::getPublishTime, new Date()));
        List<Integer> resultList = list.stream().map(WmNews::getId).collect(Collectors.toList());
        return resultList;
    }

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Override
    public PageResponseResult findListAndPage(NewsAuthDto dto) {
        //1.检查参数
        //设置起始页
        dto.setPage((dto.getPage() - 1) * dto.getSize());
        dto.setTitle("%" + dto.getTitle() + "%");

        //2.分页查询
        List<WmNewsVo> list = wmNewsMapper.findListAndPage(dto);
        //统计多少条数据
        int count = wmNewsMapper.findListCount(dto);

        //3.结果返回
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), count);
        responseResult.setData(list);
        return responseResult;
    }

    @Autowired
    private WmUserMapper wmUserMapper;

    @Override
    public WmNewsVo findWmNewsVo(Integer id) {
        //1.查询文章信息
        WmNews wmNews = getById(id);
        //2.查询作者
        WmUser wmUser = null;
        if (wmNews != null && wmNews.getUserId() != null) {
            wmUser = wmUserMapper.selectById(wmNews.getUserId());
        }

        //3.封装vo信息返回
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews, wmNewsVo);
        if (wmUser != null) {
            wmNewsVo.setAuthorName(wmUser.getName());
        }
        return wmNewsVo;
    }


    private void saveNewsMaterial(List<String> imageList, Integer newsId, Short type) {
        //通过 登录id、素材集合 来进行查询数据
        LambdaQueryWrapper<WmMaterial> materiaWrapper = new LambdaQueryWrapper<>();
        materiaWrapper.eq(WmMaterial::getUserId, ThreadLocalUtils.getUserId());
        materiaWrapper.in(WmMaterial::getUrl, imageList);
        List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(materiaWrapper);
        //之后赋值到另一个集合中
        List<String> ids = wmMaterials.stream().map(m -> m.getId() + "").collect(Collectors.toList());
        wmNewsMaterialMapper.saveRelationsByContent(ids, newsId, type);
    }

    private void saveRelations(WmNewsDto wmNews, WmNews news) {
        //返回一个id
        Integer newsId = news.getId();
        //定义一个集合存储传过来的素材
        ArrayList<String> imageList = new ArrayList<>();
        String content = wmNews.getContent();
        JSONArray objects = JSON.parseArray(content);
        objects.forEach(o -> {
            JSONObject object = JSONObject.parseObject(o.toString());
            if (object.getString("type").equals("image")) {
                String image = object.getString("value");
                imageList.add(image.replace(baseUrl, ""));
            }
        });
        //对素材表查询数据之后，然后中间表的保存
        saveNewsMaterial(imageList, newsId, WemediaContans.WM_CONTENT_REFERENCE);

        //以上为内容素材与新闻表的关系处理,下面为封面图片与新闻表的关系

        if (wmNews.getType() != null) {//没有选择自动
            List<String> images = wmNews.getImages();
            if (images != null && images.size() != 0) {
                images = images.stream().map(i -> i.replace(baseUrl, "")).collect(Collectors.toList());
                saveNewsMaterial(images, newsId, WemediaContans.WM_COVER_REFERENCE);

                WmNews updateImages = new WmNews();
                StringBuilder builder = new StringBuilder();
                for (String url : images) {
                    builder.append(url).append(",");
                }
                String image = builder.toString().substring(0, builder.toString().length() - 1);
                updateImages.setImages(image);
                updateImages.setId(news.getId());
                updateById(updateImages);
            }
        } else {//自动的,要根据内容的图片进行
            WmNews updateImages = new WmNews();
            updateImages.setId(newsId);
            if (imageList.size() != 0) {
                List<String> autoCoverUrls = imageList.size() < 3 ? Arrays.asList(imageList.get(0))
                        : Arrays.asList(imageList.get(0), imageList.get(1), imageList.get(2));
                saveNewsMaterial(autoCoverUrls, newsId, WemediaContans.WM_COVER_REFERENCE);

                StringBuilder builder = new StringBuilder();
                for (String url : autoCoverUrls) {
                    builder.append(url).append(",");
                }
                String images = builder.toString().substring(0, builder.toString().length() - 1);
                updateImages.setImages(images);
                updateImages.setType(autoCoverUrls.size() < 3 ? WemediaContans.WM_NEWS_SINGLE_IMAGE : WemediaContans.WM_NEWS_MANY_IMAGE);
            } else {
                updateImages.setImages("");
                updateImages.setType(WemediaContans.WM_NEWS_NONE_IMAGE);
            }
            updateById(updateImages);
        }
    }
}
